namespace OpenComposite.EII.Repository
{
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Drawing;
	using System.Drawing.Design;
	using System.Windows.Forms;
	using System.Xml;
	using System.Xml.Serialization;

	using OpenComposite.EII.Forms;
	using OpenComposite.EII.RepositoryUIs;

	using OpenComposite.Base.Collections;
	using OpenComposite.Repository.Properties;
	using OpenComposite.Repository.TFS;

	[RepositoryItem(ItemType.WebService, "webservices", "websvc_id")]
	public class WebService : RepositoryItemBaseEx
	{
		#region Initialization

		/// <summary>
		/// Initializes a new instance of the <see cref="WebService"/> class.
		/// </summary>
		public WebService()
			: base("websvc_id", "websvc_nm", "websvc_desc", "websvc_ntext", "<New WebService>")
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="WebService"/> class.
		/// </summary>
		/// <param name="bCreateNew">if set to <c>true</c> [b create new].</param>
		public WebService(bool bCreateNew)
			: this()
		{
			if ( bCreateNew )
				this.CreateNew();
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="WebService"/> class.
		/// </summary>
		/// <param name="id">The id.</param>
		public WebService(int id)
			: this()
		{
			this.Load(id);
		}

		#endregion Initialization

		#region Public Members

		#region Properties

		/// <summary>
		/// Gets the allowed child types.
		/// </summary>
		/// <value>The allowed child types.</value>
		public override List<ItemType> AllowedChildTypes
		{
			get { return _LISTALLOWED; }
		}

		/// <summary>
		/// Gets or sets the full name of the client.
		/// </summary>
		/// <value>The full name of the client.</value>
		public string ClientFullName
		{
			get { return getString("websvc_clientfullname", ""); }
			set { setValue("ClientFullName", "websvc_clientfullname", value); }
		}

		/// <summary>
		/// Gets or sets the contract C sharp code.
		/// </summary>
		/// <value>The contract C sharp code.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string ContractCSharpCode
		{
			get { return getString("websvc_contractcs", ""); }
			set { setValue("ContractCSharpCode", "websvc_contractcs", value); }
		}

		/// <summary>
		/// Gets the extended properties.
		/// </summary>
		/// <value>The extended properties.</value>
		public WebServiceProperties ExtendedProperties
		{
			get
			{
				if ( _properties == null ) {
					_properties = getXmlSerializedObject<WebServiceProperties>("websvc_ntext");
					if ( _properties == null )
						_properties = new WebServiceProperties();
				}
				return _properties;
			}
		}

		/// <summary>
		/// Gets the image.
		/// </summary>
		/// <value>The image.</value>
		public override Image Image
		{
			get { return Resources.png_webservice; }
		}

		/// <summary>
		/// Gets the image key.
		/// </summary>
		/// <value>The image key.</value>
		public override string ImageKey
		{
			get
			{
				return "webservice";
			}
		}

		/// <summary>
		/// Gets or sets the full name of the interface.
		/// </summary>
		/// <value>The full name of the interface.</value>
		public string InterfaceFullName
		{
			get { return getString("websvc_interfacefullname", ""); }
			set { setValue("InterfaceFullName", "websvc_interfacefullname", value); }
		}

		/// <summary>
		/// Gets or sets the meta data.
		/// </summary>
		/// <value>The meta data.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string MetaData
		{
			get { return getString("websvc_metadata", ""); }
			set { setValue("MetaData", "websvc_metadata", value); }
		}

		/// <summary>
		/// Gets or sets the namespace.
		/// </summary>
		/// <value>The namespace.</value>
		public string Namespace
		{
			get { return getString("websvc_xmlns", ""); }
			set { setValue("Namespace", "websvc_xmlns", value); }
		}

		/// <summary>
		/// Gets the type of the repository item.
		/// </summary>
		/// <value>The type of the repository item.</value>
		public override ItemType RepositoryItemType
		{
			get { return ItemType.WebService; }
		}

		/// <summary>
		/// Gets the repository item type description.
		/// </summary>
		/// <value>The repository item type description.</value>
		public override string RepositoryItemTypeDescription
		{
			get { return ""; }
		}

		/// <summary>
		/// Gets the name of the repository item type.
		/// </summary>
		/// <value>The name of the repository item type.</value>
		public override string RepositoryItemTypeName
		{
			get { return Resources.sWebService; }
		}

		/// <summary>
		/// Gets the selected image.
		/// </summary>
		/// <value>The selected image.</value>
		public override Image SelectedImage
		{
			get { return this.Image; }
		}

		/// <summary>
		/// Gets the selected image key.
		/// </summary>
		/// <value>The selected image key.</value>
		public override string SelectedImageKey
		{
			get { return this.ImageKey; }
		}

		/// <summary>
		/// Gets the name of the table.
		/// </summary>
		/// <value>The name of the table.</value>
		public override string TableName
		{
			get { return "webservices"; }
		}

		/// <summary>
		/// Gets or sets the type.
		/// </summary>
		/// <value>The type.</value>
		public ServiceType Type
		{
			get { return (ServiceType)getInt("websvc_type", 0); }
			set { setValue("Type", "websvc_type", value); }
		}

		/// <summary>
		/// Gets or sets the URI.
		/// </summary>
		/// <value>The URI.</value>
		public string Uri
		{
			get { return getString("websvc_uri", ""); }
			set { setValue("Uri", "websvc_uri", value); }
		}

		/// <summary>
		/// Gets or sets the WSDL.
		/// </summary>
		/// <value>The WSDL.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public XmlDocument WSDL
		{
			get { return getXmlDocument("websvc_wsdl"); }
			set { setXmlDocument("WSDL", "websvc_wsdl", value); }
		}

		#endregion Properties

		#region Methods

		/// <summary>
		/// Copies this instance.
		/// </summary>
		/// <param name="deep"><c>true</c> to recursively copy the item and all subitems;
		/// <c>false</c> to copy only the item itself.</param>
		/// <returns>The copied item.</returns>
		public override IRepositoryItem Copy(bool deep)
		{
			WebService copy = new WebService(true);
			copy.InitializeServiceProvider(this);
			this.CopyDataRowToTarget(copy);
			return copy;
		}

		/// <summary>
		/// Deletes this instance.
		/// </summary>
		/// <param name="bAsk">if set to <c>true</c> show a message to ask for deleting.</param>
		/// <returns></returns>
		public override bool Delete(bool bAsk)
		{
			int wsid = this.ID;
			BindingListEx<WebMethod> lstWebMethods = this.GetWebMethods();
			bool ok = base.Delete(bAsk);
			if ( ok ) {
				Global.Data.RemoveWebServiceServices(wsid);
				if ( lstWebMethods != null && lstWebMethods.Count > 0 ) {
					foreach ( WebMethod wm in lstWebMethods ) {
						wm.Delete(false);
					}
				}
			}
			return ok;
		}

		/// <summary>
		/// Gets the icon.
		/// </summary>
		/// <returns></returns>
		public override Icon GetIcon()
		{
			return Icon.FromHandle(Resources.png_webservice.GetHicon());
		}

		/// <summary>
		/// Gets the web methods.
		/// </summary>
		/// <returns></returns>
		public BindingListEx<WebMethod> GetWebMethods()
		{
			//BindingListEx<WebMethod> lstWebMethods = Global.Data.GetRepositoryHierarchyChildRepositoryList<WebMethod>(
			//    this.RepositoryItemType, this.ID, ItemType.WebMethod);
			//return lstWebMethods;
			return Global.Data.GetWebMethodsOfWebServices(this.ID);
		}

		/// <summary>
		/// Saves this instance.
		/// </summary>
		/// <returns></returns>
		public override bool Save()
		{
			if ( _properties != null )
				setXmlSerializedObject("ExtendedProperties", "websvc_ntext", _properties);

			return base.Save();
		}

		/// <summary>
		/// Shows the new item form.
		/// </summary>
		/// <param name="idRepository">The repository ID.</param>
		/// <param name="bAllowContinue">if set to <c>true</c> to allow save and continue.</param>
		/// <param name="parentItem">The parent item.</param>
		/// <param name="idDomain">The domain ID.</param>
		/// <param name="parentItemNew">The new parent item.</param>
		/// <returns></returns>
		public override DialogResult ShowNewItemForm(int idRepository, bool bAllowContinue,
			IRepositoryItem parentItem, ref int idDomain, out IRepositoryItem parentItemNew)
		{
			FormCreateNewBase dlg;
			if ( this.Type == ServiceType.APIService ) {
				dlg = new FormCreateNewAPIService(this, idRepository, bAllowContinue);
			} else {
				dlg = new FormCreateNewWebService(this, idRepository, bAllowContinue);
			}
			dlg.DomainID = idDomain;
			dlg.ParentItem = parentItem;
			DialogResult result = dlg.ShowDialog();
			if ( result == DialogResult.OK || result == DialogResult.Retry ) {
				idDomain = dlg.DomainID;
				parentItemNew = dlg.NewParentItem;
			} else {
				idDomain = 0;
				parentItemNew = null;
			}
			return result;
		}

		#endregion Methods

		#endregion Public Members

		#region Protected Members

		#region Methods

		protected override void OnDestroying(System.ComponentModel.CancelEventArgs e)
		{
			// destroy web methods
			try {
				foreach ( var wm in this.GetWebMethods() ) {
					wm.Destroy(false);
				}
				e.Cancel = false;
			} catch {
				e.Cancel = true;
			}

			if ( e.Cancel ) return;
			base.OnDestroying(e);
		}

		/// <summary>
		/// Sets the default values.
		/// </summary>
		protected override void SetDefaultValues()
		{
			if ( row == null )
				return;

			base.SetDefaultValues();
		}

		#endregion Methods

		#endregion Protected Members

		#region Private Members

		#region Static Fields

		private static List<ItemType> _LISTALLOWED =
			new List<ItemType>(new ItemType[] { ItemType.WebMethod });

		#endregion Static Fields

		#region Fields

		private WebServiceProperties _properties = null;

		#endregion Fields

		#endregion Private Members

		#region Enumerations

		public enum ServiceType
		{
			WebService = 0,
			APIService = 1
		}

		#endregion Enumerations
	}

	public class WebServiceProperties
	{
		#region Public Members

		#region Properties

		/// <summary>
		/// Gets or sets the project location.
		/// </summary>
		/// <value>The project location.</value>
		public string ProjectLocation
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the TFS server URI.
		/// </summary>
		/// <value>The TFS server URI.</value>
		public string TfsServerUri
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the name of the TFS workspace.
		/// </summary>
		/// <value>The name of the TFS workspace.</value>
		public string TfsWorkspaceName
		{
			get;
			set;
		}

		#endregion Properties

		#endregion Public Members
	}
}